// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
use std::{
    fs::{create_dir_all, OpenOptions},
    io::Write,
    path::Path,
    process::Command,
};

#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[tauri::command]
fn open_file(path: &str) -> Result<(), String> {
    // 使用 std::process::Command 打开文件（跨平台方式）
    let path_value = Path::new(path);
    let parent_path = path_value.parent().unwrap().to_str().unwrap();
    #[cfg(target_os = "windows")]
    {
        Command::new("cmd")
            .current_dir(parent_path)
            .args(&["/C", "start", "", path])
            .spawn()
            .map_err(|e| e.to_string())?;
    }

    #[cfg(target_os = "macos")]
    {
        Command::new("open")
            .arg(path)
            .spawn()
            .map_err(|e| e.to_string())?;
    }

    #[cfg(target_os = "linux")]
    {
        Command::new("xdg-open")
            .arg(path)
            .spawn()
            .map_err(|e| e.to_string())?;
    }

    Ok(())
}

// 写入文件到指定路径
#[tauri::command]
fn write_file_str(path: String, data: String) -> Result<(), String> {
    // 将路径转换为 Path
    let file_path = Path::new(&path);
    // 如果父目录不存在，则创建所有必要的父目录
    if let Some(parent_dir) = file_path.parent() {
        if !parent_dir.exists() {
            create_dir_all(parent_dir).map_err(|e| e.to_string())?;
        }
    }
    let mut file = OpenOptions::new()
        .create(true)
        .append(false)
        .open(&path)
        .map_err(|e| e.to_string())?;
    file.write(&data.as_bytes()).map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
fn execute_command(command: &str) -> Result<(), String> {
    let output = Command::new("cmd")
        .args(&["/C", command])
        .output()
        .map_err(|e| e.to_string())?;

    if output.status.success() {
        Ok(())
    } else {
        Err(String::from_utf8_lossy(&output.stderr).to_string())
    }
}

#[tauri::command]
fn save_file(path: String, chunk: Vec<u8>) -> Result<(), String> {
    // 将路径转换为 Path
    let file_path = Path::new(&path);

    // 如果父目录不存在，则创建所有必要的父目录
    if let Some(parent_dir) = file_path.parent() {
        if !parent_dir.exists() {
            create_dir_all(parent_dir).map_err(|e| e.to_string())?;
        }
    }

    let mut file = OpenOptions::new()
        .create(true)
        .append(true)
        .open(&path)
        .map_err(|e| e.to_string())?;
    file.write(&chunk).map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
fn remove_file(path: String) -> Result<(), String> {
    // 将路径转换为 Path
    let file_path = Path::new(&path);
    if file_path.exists() {
        std::fs::remove_file(file_path).map_err(|e| e.to_string())?;
    }
    Ok(())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![
            greet,
            open_file,
            execute_command,
            save_file,
            remove_file,
            write_file_str
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
